package org.rcgwt.client.ui.grid.renderer;

import org.rcgwt.client.theme.CssStyle;
import org.rcgwt.client.ui.grid.internal.model.ICellModel;

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.user.client.ui.Widget;

/**
 * This abstract render draw the Cell You should extends this Class for set a
 * {@link Widget}
 * 
 * @author Matthieu ROBERT
 * 
 */
public abstract class AbstractCellRenderer extends AbstractRenderer<ICellModel>
        implements ICellRenderer {

    private static final String WIDGET_REGISTRED_ATTRIBUTE = "wregistred";

    public Element render(IViewRenderContext viewRenderContext,
            Element parentComponent, ICellModel cell, int renderedIndex) {

        assert parentComponent instanceof TableRowElement : "Invalid parent type ("
                + parentComponent + ")";

        TableCellElement cellElement = parentComponent.getOwnerDocument()
                .createTDElement();

        update(viewRenderContext, cellElement, cell, renderedIndex);

        return cellElement;
    }

    @Override
    public void update(IViewRenderContext viewRenderContext,
            Element cellElement, ICellModel cell, int renderedIndex) {
        super.update(viewRenderContext, cellElement, cell, renderedIndex);

        viewRenderContext.getViewModel().getViewModelElements().setCellElement(
                cell, cellElement, renderedIndex);
    }

    @Override
    protected CssStyle getCssStyle(IViewRenderContext viewRenderContext,
            ICellModel cell) {

        IGridRenderContext gridRenderContext = viewRenderContext
                .getGridRenderContext();

        return gridRenderContext.getTheme().getCellStyleName(gridRenderContext,
                cell);
    }

    @Override
    protected void updateContent(IViewRenderContext viewRenderContext,
            Element element, ICellModel cell) {
        int widgetId = element.getPropertyInt(WIDGET_REGISTRED_ATTRIBUTE);
        if (widgetId > 0) {
            element.setPropertyString(WIDGET_REGISTRED_ATTRIBUTE, null);

            viewRenderContext.getGridRenderContext().getGridModel()
                    .getGridWidget().getWidgetsRegistry().remove(widgetId);
        }

        // Supprime les sous éléments éventuelles
        while (element.getFirstChild() != null) {
            element.removeChild(element.getFirstChild());
        }

        appendCellContent(viewRenderContext.getGridRenderContext(), element,
                cell);
    }

    protected void appendCellContent(IGridRenderContext gridRenderContext,
            Element td, ICellModel cell) {

        Widget widget = getWidget(gridRenderContext, cell);
        if (widget == null) {
            td.setInnerText(String.valueOf(getValue(gridRenderContext, cell)));
            return;
        }

        int widgetId = gridRenderContext.getGridModel().getGridWidget()
                .getWidgetsRegistry().add(widget);

        td.setPropertyInt(WIDGET_REGISTRED_ATTRIBUTE, widgetId);

        td.appendChild(widget.getElement());
    }

    protected Object getValue(IGridRenderContext gridRenderContext,
            ICellModel cell) {
        return gridRenderContext.getGridModel().getGridWidget().getDataModel()
                .getValueAt(cell.getModelIndex(),
                        cell.getColumnModel().getColumn().getName());
    }

    protected abstract Widget getWidget(IGridRenderContext renderContext,
            ICellModel cell);
}
